package com.hlg.xboot.service.modules;

import com.hlg.xboot.constants.AppConstants;
import com.hlg.xboot.dao.modules.UserRepository;
import com.hlg.xboot.enums.Status;
import com.hlg.xboot.exceptions.ParameterException;
import com.hlg.xboot.exceptions.RecordDuplicateException;
import com.hlg.xboot.exceptions.RecordNotFoundException;
import com.hlg.xboot.exceptions.ServerBizException;
import com.hlg.xboot.model.modules.User;
import com.hlg.xboot.service.BaseService;
import com.digi_zones.common.utils.CommonUtils;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>Description:用户</p>
 * <p>Copyright: Copyright (c) 2016</p>
 * <p>Company: 中视数讯</p>
 * <p>Site: www.digi-zones.com</p>
 *
 * @author gaol
 * @version 1.0
 * @date 2016/10/25
 */
@Service
public class UserService extends BaseService<User, UserRepository> {

    public User findByOpenid(String openid) throws ServerBizException {
        return repository.findOneByOpenid(openid);
    }

    public User findByPhone(String phone) throws ServerBizException {
        return repository.findOneByPhone(phone);
    }

    /**
     * 根据用户名查找用户
     * @param username 用户名
     * @return 用户对象
     */
    public User findByUsername(String username){
        return repository.findOneByUsername(username);
    }

    /**
     * 用户是否存在
     * @param username 用户名
     * @return
     * @throws Exception
     */
    public boolean exists(String username) throws ServerBizException {
        return repository.findOneByUsername(username) != null;
    }

    /**
     * 登录
     * @param username 用户名
     * @param password 密码
     * @return 用户信息
     * @throws Exception
     */
    public User login(String username, String password, HttpServletRequest request) throws ServerBizException {
        if (StringUtils.isEmpty(username)) {
            throw new ParameterException("用户名不能为空");
        }
        if (StringUtils.isEmpty(password)) {
            throw new ParameterException("密码不能为空");
        }
        User user = (User) request.getSession().getAttribute(AppConstants.SESSION_USER);
        password = DigestUtils.md5Hex(password);
        if (user == null) {
            final String finalPassword = password;
            List<User> users = findAll(new Specification<User>() {
                @Override
                public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                    List<Predicate> predicates = new ArrayList<Predicate>();
                    predicates.add(cb.and(cb.equal(root.get("password"), finalPassword)));
                    List<Predicate> orPredicates = new ArrayList<Predicate>();
                    orPredicates.add(cb.equal(root.get("username"),username));
                    orPredicates.add(cb.equal(root.get("phone"),username));
                    predicates.add(cb.or(orPredicates.toArray(new Predicate[orPredicates.size()])));
                    return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
                }
            });
            if (CollectionUtils.isEmpty(users)) {
                throw new RecordNotFoundException("用户名或密码不正确");
            }
            user = users.get(0);
        } else {
            if (!(password.equals(user.getPassword()) && username.equals(user.getUsername()))) {
                throw new ParameterException("用户名或密码不正确");
            }
        }
        user.setLastLoginIP(CommonUtils.getClientIPAddress(request));
        user.setLastLoginTime(new Date());
        update(user);
        return user;
    }

    /**
     * 新增或注册
     * @param user
     * @return
     * @throws ServerBizException
     */
    @Override
    public User add(User user) throws ServerBizException {
        if (exists(user.getUsername())) {
            throw new RecordDuplicateException("用户名已注册");
        }
        if (findByPhone(user.getPhone()) != null) {
            throw new RecordDuplicateException("该手机号已绑定其它用户");
        }
        user.setStates(Status.ENABLED.getValue());
        user.setPassword(DigestUtils.md5Hex(user.getPassword()));
        return super.add(user);
    }

    /**
     * 更新
     * @param user
     * @return
     * @throws ServerBizException
     */
    @Override
    public User update(User user) throws ServerBizException {
        User _user = repository.getOne(user.getId());
        if(_user == null){
            throw new RecordNotFoundException("用户不存在");
        }
        if(!_user.getUsername().equals(user.getUsername())) {
            if (exists(user.getUsername())) {
                throw new RecordDuplicateException("用户名已注册");
            }
        }
        if(!_user.getPhone().equals(user.getPhone())) {
            if (findByPhone(user.getPhone()) != null) {
                throw new RecordDuplicateException("该手机号已绑定其它用户");
            }
        }
        return repository.save(user);
    }
}
